//
// Created by alfielin on 2021/11/12.
//

#pragma once

#include <unordered_map>

namespace nz {
namespace werewolf {

#define NZDEBUG_WEREWOLF

#define ERR_CODE_MAP(XX) \
    XX(-1,      UNKNOWN,            Unknown)      \
    XX(-1001,   NO_SUCH_USER,       No such user) \
    XX(-1002,   NO_SUCH_ROOM,       No such room) \
    XX(-1003,   INVALID_OPERATION,   Invalid operation)\

struct ERRCODE {
#define XX(num, name, msg) static const int X##name;
    ERR_CODE_MAP(XX)
#undef XX
};
#define XX(num, name, msg) const int ERRCODE::X##name = num;
ERR_CODE_MAP(XX)
#undef XX

struct ERRMSG {
#define XX(num, name, msg) static const char* X##name;
    ERR_CODE_MAP(XX);
#undef XX
};
#define XX(num, name, msg) const char* ERRMSG::X##name = #msg;
ERR_CODE_MAP(XX)
#undef XX


enum class RoleT {
    VILLAGER,
    PROPHET,
    WITCH,
    HUNTER,
    GUARDIAN,
    IDIOT,
    JUPITER,
    WOLF,
    WOLF_KING,
    WOLF_HUNTER,
    SUNRISE,
    UGLY_COUNT_
};

enum class ActionT {
    VOTE = 0,               // vote who to exile
    SUNSET = 1,             // sunset
    SHOOT = 2,              // hunter shoots
    WOLF_SUICIDE = 3,       // werewolf suicide
    KING_SUICIDE = 4,       // werewolf king suicide
    NIGHT_NEXT = 5,         // triggers the next handler
    NIGHT_ACT = 6,          // woke up role take action at night
};

const std::string POISON_TAG = "POISON";

const std::unordered_map<int, std::string> ROLE_NAME_MAP = {
        { int(RoleT::VILLAGER),    "VILLAGER" },
        { int(RoleT::PROPHET),     "PROPHET" },
        { int(RoleT::WITCH),       "WITCH" },
        { int(RoleT::HUNTER),      "HUNTER" },
        { int(RoleT::GUARDIAN),    "GUARDIAN" },
        { int(RoleT::IDIOT),       "IDIOT" },
        { int(RoleT::JUPITER),     "JUPITER" },
        { int(RoleT::WOLF),        "WOLF" },
        { int(RoleT::WOLF_KING),   "WOLF_KING" },
        { int(RoleT::WOLF_HUNTER), "WOLF_HUNTER" },
        { int(RoleT::SUNRISE),     "SUNRISE" },
        { int(RoleT::UGLY_COUNT_), "UGLY_COUNT" }
};

}
}
